# -*- coding: utf-8 -*-
import json
import requests

from common import log, DEBUG, generate_word_dict, calculate_alphabet_frequency, \
    loads_local_words

__author__ = 'raniys'

REQUEST_TIMEOUT = 300
SERVER_ADDRESS = "https://strikingly-hangman.herokuapp.com/game/on"


class Strikingly(object):
    sessionId = ''
    numberOfGuessAllowedForEachWord = 0
    numberOfWordsToGuess = 0
    word = ''
    usedChars = ''
    score = None
    totalWordCount = 0
    wrongGuessCountOfCurrentWord = 0
    correctWordCount = 0
    totalWrongGuessCount = 0

    def __init__(self, player_id):
        if player_id:
            self.player_id = player_id
        else:
            raise Exception('Need player_id to init')

    def start_game(self):
        params = dict(playerId=self.player_id, action="startGame")
        response = requests.post(SERVER_ADDRESS, json=params, timeout=REQUEST_TIMEOUT)
        if response.status_code == 200:
            result = json.loads(response.content)
            self.sessionId = result['sessionId']
            self.numberOfGuessAllowedForEachWord = result['data']['numberOfGuessAllowedForEachWord']
            self.numberOfWordsToGuess = result['data']['numberOfWordsToGuess']
            print('==>: {}, sessionId: {}'.format(result['message'], result['sessionId']))
        else:
            print('Request start_game error: {}'.format(response.status_code))

    def give_me_a_word(self):
        """
        Word Difficulty:
        # 1st to 20th word : length <= 5 letters
        # 21st to 40th word : length <= 8 letters
        # 41st to 60th word : length <= 12 letters
        # 61st to 80th word : length > 12 letters
        """
        params = dict(sessionId=self.sessionId, action="nextWord")
        response = requests.post(SERVER_ADDRESS, json=params, timeout=REQUEST_TIMEOUT)
        if response.status_code == 200:
            result = json.loads(response.content)
            self.usedChars = ''
            self.word = result['data']['word']
            self.totalWordCount = result['data']['totalWordCount']
            self.wrongGuessCountOfCurrentWord = result['data']['wrongGuessCountOfCurrentWord']
            log(Word=self.word, Guess='', Used='', totalWordCount=self.totalWordCount)
            return True
        else:
            print('Request give_me_a_word error: {}'.format(response.status_code))
            return False

    def make_a_guess(self, char):
        params = dict(sessionId=self.sessionId, action="guessWord", guess=char)
        response = requests.post(SERVER_ADDRESS, json=params, timeout=REQUEST_TIMEOUT)
        if response.status_code == 200:
            result = json.loads(response.content)
            self.usedChars += char
            self.wrongGuessCountOfCurrentWord = result['data']['wrongGuessCountOfCurrentWord']
            if self.word != result['data']['word']:
                self.word = result['data']['word']
            if DEBUG:
                log(Word=self.word, Guess=char, Used=self.usedChars)
        else:
            print('Request make_a_guess error: {}'.format(response.status_code))

    def get_result(self):
        params = dict(sessionId=self.sessionId, action="getResult")
        response = requests.post(SERVER_ADDRESS, json=params, timeout=REQUEST_TIMEOUT)
        if response.status_code == 200:
            result = json.loads(response.content)
            self.score = result['data']['score']
            self.correctWordCount = result['data']['correctWordCount']
            self.totalWrongGuessCount = result['data']['totalWrongGuessCount']
            log(Score=self.score, TotalWordCount=self.totalWordCount, CorrectWordCount=self.correctWordCount,
                TotalWrongGuessCount=self.totalWrongGuessCount)
        else:
            print('Request get_result error: {}'.format(response.status_code))

    def submit_result(self):
        params = dict(sessionId=self.sessionId, action="submitResult")
        response = requests.post(SERVER_ADDRESS, json=params, timeout=REQUEST_TIMEOUT)
        if response.status_code == 200:
            result = json.loads(response.content)
            print "Your score has submitted: "
            print result
        else:
            print('Request submit_result error: {}'.format(response.status_code))


class HangmanGame(object):
    def __init__(self):
        print "Welcome to 'Hangman', are you ready?"
        print "(1)Yes, I am ready.\n(2)No, get me outta here!"
        user_choice_1 = raw_input("->")
        if user_choice_1 == '1':
            print "Loading..."
            self.start()
        elif user_choice_1 == '2':
            print "Bye..."
            exit()
        else:
            print "I'm sorry, I'm hard of hearing, could you repeat that?"
            self.__init__()

    def start(self):
        word_list = [w.upper() for w in loads_local_words()]
        word_dict, sorted_alphabet_frequency = generate_word_dict(list(set(word_list)))

        game = Strikingly("Chengjia_Liao@hotmail.com")
        game.start_game()
        past_words = []
        while game.totalWordCount < 80:
            game.give_me_a_word()
            word_len = len(game.word)
            word_list = word_dict[word_len][:]
            sorted_character_frequency = sorted_alphabet_frequency[word_len][:]
            while game.wrongGuessCountOfCurrentWord < game.numberOfGuessAllowedForEachWord:
                if not sorted_character_frequency:
                    print 'WARNING: no match word in local dict !!!!!'
                    break

                guess_alphabet = sorted_character_frequency[0][0]
                game.make_a_guess(guess_alphabet)

                if '*' in game.word:
                    word_list, sorted_character_frequency = calculate_alphabet_frequency(word_list, game.word,
                                                                                         game.usedChars)
                else:
                    if game.word in word_dict[len(game.word)]:
                        index = word_dict[len(game.word)].index(game.word)
                        del word_dict[len(game.word)][index]
                    break

            past_words.append(game.word)
            print ','.join(past_words)
            game.get_result()

        print "GAME OVER!"
        print "Calculate your score..."
        game.get_result()

        print "Would you like submit your score?"
        print "(1)Yes, please submit my new score.\n(Others)No, please do not!"
        user_choice_2 = raw_input("->")
        if user_choice_2 == '1':
            print "Submitting..."
            game.submit_result()

        self.run_again()

    def run_again(self):
        print "Would you like play again?"
        print "(1)Yes.\n(2)No, get me outta here!"
        user_choice_3 = raw_input("->")
        if user_choice_3 == '1':
            print "Loading..."
            self.start()
        elif user_choice_3 == '2':
            print "Bye..."
            exit()
        else:
            print "I'm sorry, I'm hard of hearing, could you repeat that?"
            self.run_again()


HangmanGame().start()
